#include "Rotate.h"
#include "rotationitem.h"
#include "../VMain.h"
#include "../VPicture.h"
#include "../VContainer.h"

#ifdef UNDER_CE
#define KPI 3.1415926
static void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear,  GLfloat zFar)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    double xmin, xmax, ymin, ymax;
    ymax = zNear * tan(fovy * KPI / 360);
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;

    glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
    glMatrixMode(GL_MODELVIEW);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glDepthMask(GL_TRUE);
}

static void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,

                      GLfloat centerx, GLfloat centery, GLfloat centerz,

                      GLfloat upx, GLfloat upy, GLfloat upz)

{

    GLfloat m[16];

    GLfloat x[3], y[3], z[3];

    GLfloat mag;


    /* Make rotation matrix */

    /* Z vector */

    z[0] = eyex - centerx;

    z[1] = eyey - centery;

    z[2] = eyez - centerz;

    mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);

    if (mag)                     /* mpichler, 19950515 */
    {

        z[0] /= mag;

        z[1] /= mag;

        z[2] /= mag;

    }

    /* Y vector */

    y[0] = upx;

    y[1] = upy;

    y[2] = upz;

    /* X vector = Y cross Z */

    x[0] = y[1] * z[2] - y[2] * z[1];

    x[1] = -y[0] * z[2] + y[2] * z[0];

    x[2] = y[0] * z[1] - y[1] * z[0];

    /* Recompute Y = Z cross X */

    y[0] = z[1] * x[2] - z[2] * x[1];

    y[1] = -z[0] * x[2] + z[2] * x[0];

    y[2] = z[0] * x[1] - z[1] * x[0];

    /* mpichler, 19950515 */

    /* cross product gives area of parallelogram, which is < 1.0 for

    * non-perpendicular unit-length vectors; so normalize x, y here

    */

    mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);

    if (mag)
    {

        x[0] /= mag;

        x[1] /= mag;

        x[2] /= mag;

    }

    mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);

    if (mag)
    {

        y[0] /= mag;

        y[1] /= mag;

        y[2] /= mag;

    }

#define M(row,col)  m[col*4+row]

    M(0, 0) = x[0];

    M(0, 1) = x[1];

    M(0, 2) = x[2];

    M(0, 3) = 0.0;

    M(1, 0) = y[0];

    M(1, 1) = y[1];

    M(1, 2) = y[2];

    M(1, 3) = 0.0;

    M(2, 0) = z[0];

    M(2, 1) = z[1];

    M(2, 2) = z[2];

    M(2, 3) = 0.0;

    M(3, 0) = 0.0;

    M(3, 1) = 0.0;

    M(3, 2) = 0.0;

    M(3, 3) = 1.0;

#undef M

    glMultMatrixf(m);
    /* Translate Eye to Origin */
    glTranslatef(-eyex, -eyey, -eyez);
}
#endif

float CRotate::playtime = 300.0;
CRotate::CRotate(void)
{
    m_bIsPlaying     = false;
    m_flag           = 0;
    m_dwStartTime    = 0;
    m_fPosPerSeconds = 0;

    Init();
}

CRotate::~CRotate(void)
{
}

void CRotate::start(int ndirection)
{
    m_flag = ndirection;
    m_dwStartTime = VMain::getClock();
    m_bIsPlaying  = true;
}

void CRotate::stop()
{
    m_flag           = 0;
    m_dwStartTime    = 0;
    m_fPosPerSeconds = 0;
    m_bIsPlaying     = false;
}

void CRotate::Update()
{
    if (0 == m_flag)
    {
        return;
    }

    int j = 0;
    float dwTmp = VMain::getClock() - m_dwStartTime;

    m_fPosPerSeconds = dwTmp / playtime;

    //   DEBUG_OUTPUT("%d",m_fPosPerSeconds);
    VWidgetArray::iterator it = _children->begin();
    float fAngle1 = 0;

    if (m_fPosPerSeconds >  1.0)
    {
        RotationItem* item;

        for (; it != _children->end(); ++it)
        {
            item = (RotationItem*)(*it);
            item->m_fAngle = item->m_fAngleBK + 45 * m_flag;

            if ((int)(item->m_fAngle) % 360 == 0)
            {
                item->m_fAngle = 0;
            }

            item->m_fAngleBK = item->m_fAngle;
        }

        stop();
        return;
    }

    float fAngle = 0;

    for (; it != _children->end(); ++it)
    {
        ((RotationItem*)(*it))->m_fAngle = ((RotationItem*)(*it))->m_fAngleBK + 45 * m_flag * m_fPosPerSeconds;
    }
}

bool CRotate::render() const
{
    bool ret = true;

    SetGLenvironment();

    VContainer::render();

    VMain::resetViewport();

    return ret;
}

void CRotate::Add(VPicture* pic)
{
    RotationItem* item;

    static int currentId = 0;

    item = new RotationItem(pic);

    item->m_fWidth = item->m_fHeight = 1.0f;
    item->m_v3Position.x = 0;
    item->m_v3Position.y = -0.5;
    item->m_v3Position.z = 3;

    item->m_fAngle   = currentId * 45;
    item->m_fAngleBK = currentId * 45;
    item->setPrivateData(new int(currentId++));

    insert(item);
}

void CRotate::Init()
{
    int i;

    for (i = 0; i != max_count; ++i)
    {
        Add(new VPicture(VMain::getSkin("language_ui\\language%d.png", i + 1)));
    }

}

void CRotate::SetGLenvironment() const
{

    glEnable(GL_DEPTH_TEST);
    //     glEnable(GL_BLEND);
    //     glEnable(GL_ALPHA);

    //     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //     glAlphaFunc(GL_ALWAYS, 0.1f);
    //     glEnable(GL_ALPHA_TEST);
    //       glViewport(0,0,800,600);
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    gluPerspective(45.0f,
                   (GLfloat)VIEWPORT_WIDTH / (GLfloat)VIEWPORT_HEIGHT,
                   1.0f, 100.0f);
    //  gluLookAt(
    //      摄像机x,摄像机y,摄像机z,
    //      目标点x,目标点y,目标点z,
    //      摄像机顶朝向x,摄像机顶朝向y,摄像机顶朝向z
    //      )
    gluLookAt(0.1, 0.6, 5.0, 0.0, 0.0, 0.0, 0.0, 1, 0.0);
    //  glOrtho(0,Width,Height,0,-1.0f,100.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void CRotate::animate(void)
{
    Update();
}

void CRotate::move(int x, int y)
{
    // unmovable
}

void CRotate::resize(int w, int h)
{
    // un-sizable
}